#!/opt/perl/bin/perl -w

#########################################################################
# Name:		mco [perl cm2 report tool]				#
#									#
# Author:	Simon Edwards, Proprius Consulting Ltd,			#
#			[simon.edwards@proprius.co.uk]			#
#									#
# Completed:	12th May, 2006.						#
#									#
# Updated:								#
#									#
# Arguments:	[--verbose] [--projects x,ab,c] [--period N[hd]]	#
#									#
#		--verbose     Verbose mode - show progress messages	#
#			      to STDOUT.				#
#		--projects    A comma separated list of projects to	#
#			      scan for changes.				#
#		--period      Go back from now for this period of 	#
#			      time - must be followed by "h" for	#
#			      hours, "d" for days (defaults to 		#
#			      days).					#
#									#
# Purpose:	Genenerates a report which covers the specified period	#
#		of time showing any files which have been updated in	#
#		this period in more than one project. When such files	#
#		exist the file name is given along with the projects	#
#		that have updated it and the developer name[s].		#
#									#
#########################################################################

BEGIN {
	push @INC,$ENV{CODEMGR_LIBS} if exists($ENV{CODEMGR_LIBS});
}

use Getopt::Long;
use codemgr2 qw(msg logmsg warnmsg errormsg load_config get_project
		get_related_project_mappings
		get_md5_of_version get_lver_of_md5_version match_version
		load_translog_after_time attempt_alias_map);
use File::Basename;
use Data::Dumper;
use Cwd;
use English;

umask 002;
$_PRG=basename($0);
$_SPC=" " x length($_PRG);
$ARG_projects=undef;
$ARG_verbose=0;
$ARG_period=undef;

sub usage {
	print "
Usage: $_PRG --projects a[,b...] --period N[hd] [--verbose] 

The $_PRG reports on any files looking back from the present over the
specified period that have been changing in more than one project.

$_PRG currently the following arguments:

--projects   The list of projects to scan [can use aliases if desired]
--period     The period of time to check back over - default is days,
             add 'h' suffix to change to hours.
--verbose    Verbose mode - show progress messages to STDOUT.

Written by Simon Edwards 2006, proprius.co.uk
";
	exit 1;
}

if(!GetOptions(
	"projects=s"		=> \$ARG_projects,
	"period=s"		=> \$ARG_period,
	"verbose"		=> \$ARG_verbose,
	)) {
	usage;
}

if(!defined($ARG_projects) || !defined($ARG_period)) {
	usage;
}

#########################################################################
# Work out the time period and if invalid issue the usage again.	#
#########################################################################

if($ARG_period =~ /^\d+$/) {
	$multi=86400;
} else {
	if($ARG_period !~ /^(\d+)([hd])$/) {
		usage;
	}
	$multi=86400 if $2 eq "d";
	$multi=3600 if $2 eq "h";
	$ARG_period=int($1);
}

$oldtime=time - ($ARG_period * $multi);

%RN=();
$PROJECTS_ROOT=$ENV{PROJECTS_ROOT};
for $cproj (split(/,/,$ARG_projects)) {
	if(! -d "$PROJECTS_ROOT/$cproj") {
		$alias=$cproj;
		$realname=attempt_alias_map($cproj);
		if(defined($realname)) {
			$cproj=$realname;
			logmsg("Matched project \"$cproj\" via alias \"$alias\".");
		} else {
			errormsg("Project source directory \"$cproj\" does not exist.",2);
		}
	}

	#################################################################
	# Now load the transload for the specified project.		#
	#################################################################
	($data,$err)=load_translog_after_time($cproj,$oldtime);
	if(defined($err)) {
		errmsg("Error encountered loading transaction details for \"$cproj\":");
		errmsg($err,1);
	}
	$RN{$cproj}=[@$data];
}

for (sort(keys(%RN))) {
	$e=scalar(@{$RN{$_}});
	logmsg(sprintf("Project %-20s has %4d updates.",$_,$e));
}

#########################################################################
# We can use a hash to generate a list of files across all projects	#
# that have been updated which each hash is a list and each list	#
# element is [projectname,user,lver]					#
#########################################################################

%ALLFILES=();
for $cproj (sort(keys(%RN))) {
	for $centry (@{$RN{$cproj}}) {
		next if $centry->[2] eq "TAG";
		$cfile=$centry->[3];
		$cuser=$centry->[1];
		$clver=$centry->[4] || "1.1";
		if(!exists($ALLFILES{$cfile})) {
			$ALLFILES{$cfile}=[];
		}
		push @{$ALLFILES{$cfile}},[$cproj,$cuser,$clver];
	}
}

# We we're only interested in any hash elements which list reference	#
# has more than one element [and for more than one project!]		#

for $cfile (sort(keys %ALLFILES)) {
	if(scalar(@{$ALLFILES{$cfile}})>1) {
		%P=();
		%D=();
		for $centry (@{$ALLFILES{$cfile}}) {
			$P{$centry->[0]}=1;
			$D{$centry->[1]}=1;
		}
		if(scalar(keys(%P))>1) {
			print "  File      :$cfile [" . scalar(@{$ALLFILES{$cfile}}) . " updates]\n";
			print "  Projects  :",join(",",sort(keys(%P))),"\n";
			print "  Developers:",join(",",sort(keys(%D))),"\n";
		}
	}
}

